'''
添加页面操作关键字
'''
# 设置显示等待
from selenium.webdriver.support.wait import WebDriverWait
# 判断是否是否可见
from selenium.webdriver.support import expected_conditions
# 鼠标相关操作
from selenium.webdriver.common.action_chains import ActionChains
from Lib.common.common_function import *
from selenium.webdriver.common.keys import Keys
from time import sleep
import time
import os
import allure
from appium.webdriver.webdriver import WebDriver


class AppKeyWords:
    '''
      页面元素相关操作的封装
    '''

    def __init__(self, driver: WebDriver):
        self.driver = driver

    def element_is_exist(self, args: tuple, context: str = None) -> bool:
        '''
        # 判断元素是否存在
        :param args: 元素参数
        :param context: 元素说明
        :return: 当元素存在时返回True 否则返回False
        '''
        try:
            WebDriverWait(self.driver, 10).until(expected_conditions.presence_of_element_located(args))
        except Exception as e:
            error_log().debug(f'{context}不存在,查找失败')
            return False
        else:
            return True

    def element_is_visible(self, args: tuple, context: str = None) -> bool:
        '''
        # 判断元素是否可见
        :param args:
        :param context:
        :return:
        '''
        try:
            WebDriverWait(self.driver, 10).until(expected_conditions.visibility_of_element_located(args))
        except Exception as e:
            error_log().debug(f'{context}不可见,查找失败')
            return False
        else:
            return True

    def elements_is_visible(self, args: tuple, context: str = None) -> bool:
        '''
        # 判断多个元素是否可见
        :param args:
        :param context:
        :return:
        '''
        try:
            WebDriverWait(self.driver, 10).until(expected_conditions.visibility_of_all_elements_located(args))
        except Exception as e:
            error_log().debug(f'{context}不可见,查找失败')
            return False
        else:
            return True

    def get_current_page_size(self) -> dict:
        '''
        # 获取当前页面大小
        :return: 返回页面大小字典 包含 width height
        '''
        return self.driver.get_window_size()

    # 混合应用h5
    def find_element(self, args, context=None):
        '''
        查找元素
        :param context
        :param args:
        :return:
        '''
        # 判断元素是否可见
        if self.element_is_visible(args, context):
            return self.driver.find_element(*args)
        else:
            raise ValueError(f"{context}元素查找失败")

    def find_elements(self, args, context=None):
        '''
        查找满足条件的所有元素
        :param context
        :param args:
        :return:
        '''
        # 判断元素是否可见
        if self.elements_is_visible(args, context):
            return self.driver.find_elements(*args)
        else:
            raise ValueError(f"{context}元素查找失败")

    def quite(self):
        '''
        关闭浏览器
        :return:
        '''
        normal_log().info('退出浏览器成功')
        self.driver.quit()

    def input_value(self, args, text, context=None):
        '''
        为输入框输入在值
        :param args:
        :param text: 需要输入的值
        :param context:
        :return:
        '''
        try:
            with allure.step(f"{context}输入{text}"):
                self.find_element(args, context).send_keys(text)
        except Exception as e:
            error_log().debug('>>>>>>>>>{0}'.format(e))
            raise ValueError("为{}元素传值失败".format(context))

    def click(self, args, context=None):
        '''
        点击某个元素
        :param args:
        :param context:
        :return:
        '''
        try:
            with allure.step(f"点击{context}"):
                self.find_element(args, context).click()
        except Exception as e:
            error_log().debug('>>>>>>>>>>>>>>>>>>>{0}'.format(e))
            raise ValueError("{}元素点击失败".format(context))

    def wait(self, second):
        '''
        设置显示等待
        :return:
        '''
        if second and type(second) is int:
            with allure.step(f'sleep{second}'):
                sleep(second)
        else:
            raise ValueError("输入的时间不合法")

    def js_click(self, args, context=None):
        '''
        使用js点击元素
        :param args:
        :param context:
        :return:
        '''
        try:
            with allure.step(f"点击{context}"):
                element = self.find_element(args, context)
                js = 'arguments[0].click()'
                self.driver.execute_script(js, element)
        except Exception as e:
            error_log().debug('js点击{0}失败'.format(context))
            error_log().debug('>>>>>>>>>>>>>>>>>>>{0}'.format(e))
            raise ValueError("使用js点击{}元素失败".format(context))

    def get_text(self, args, context=None):
        '''
        获取元素的文本信息，用作断言
        :param args:
        :param context:
        :return:
        '''
        try:
            # 判断元素是否可见
            text_element = self.find_element(args, context)
            if text_element.is_displayed():
                return text_element.text
            else:
                return text_element.get_attribute("innerText")
        except Exception as e:
            error_log().debug('>>>获取{0}文本信息失败'.format())
            error_log().debug('>>>{0}'.format(e))
            raise ValueError("获取{}的文本信息失败".format(context))

    def clear_input(self, args, context=None):
        '''
        清空输入框
        :param args:
        :param context:
        :return:
        '''
        try:
            with allure.step(f'清空{context}'):
                self.find_element(args=args, context=context).clear()
        except Exception as e:
            error_log().debug('>>>>>>清空操作失败')
            error_log().debug(e)
            raise e

    def refresh(self):
        '''
        刷新当前页面
        :return:
        '''
        try:
            with allure.step('刷新当前页面'):
                self.driver.refresh()
        except Exception as e:
            error_log().debug('>>>>>刷新当前页面失败')
            error_log().debug('>>>>>>{}'.format(e))

    def input_value_with_time(self, args, text: list, context=None):
        '''
        为时间输入框输入时间值
        :param args:
        :param text: 需要输入的值  时间格式 和
        :param context:
        :return:
        '''
        try:
            with allure.step(f"添加时间到{context}"):
                time_format = get_time(format_time=text[0], number=text[1])
                self.find_element(args, context).send_keys(time_format)
        except Exception as e:
            error_log().debug('>>>>>>>>>{0}'.format(e))
            raise ValueError("为{}元素传值失败".format(context))

    def swipe(self, args: list, context: str = None):
        '''
        设置屏幕的上下左右滑动
        :param args:  滑动的方向 取列表的第一个值 up down left right
        :param context: 说明
        :return:
        '''
        # 获取当前页面的大小
        size = self.get_current_page_size()
        # 设置滑动

        if args[0] == "up":
            # 设置滑动的大小
            start_x = size['width'] * 0.5
            start_y = size['height'] * 0.8
            end_x = size['width'] * 0.5
            end_y = size['height'] * 0.3
            with allure.step("向上进行滑动"):
                self.driver.swipe(start_x=start_x, start_y=start_y, end_x=end_x, end_y=end_y, duration=200)
        elif args[0] == "down":
            # 设置滑动的大小
            start_x = size['width'] * 0.5
            start_y = size['height'] * 0.3
            end_x = size['width'] * 0.5
            end_y = size['height'] * 0.8
            with allure.step("向上进行滑动"):
                self.driver.swipe(start_x=start_x, start_y=start_y, end_x=end_x, end_y=end_y, duration=200)
        elif args[0] == "left":
            # 设置滑动的大小
            start_x = size['width'] * 0.8
            start_y = size['height'] * 0.5
            end_x = size['width'] * 0.3
            end_y = size['height'] * 0.5
            with allure.step("向上进行滑动"):
                self.driver.swipe(start_x=start_x, start_y=start_y, end_x=end_x, end_y=end_y, duration=200)
        elif args[0] == "right":
            # 设置滑动的大小
            start_x = size['width'] * 0.3
            start_y = size['height'] * 0.5
            end_x = size['width'] * 0.8
            end_y = size['height'] * 0.5
            with allure.step("向上进行滑动"):
                self.driver.swipe(start_x=start_x, start_y=start_y, end_x=end_x, end_y=end_y, duration=200)

    def swipe_pages(self, args: list, context: str = None):
        '''
        多次滑动, 指直到找到对应的元素
        :param args:
        :param context:
        :return:
        '''
        # 定义新老页面
        old_page = None
        new_page = self.driver.page_source
        # 判断新页面是否等于老页面，不是说明当前页面不是最后一页
        with allure.step(f"滑动到{context}元素"):
            while old_page != new_page:
                # 判断当前元素是否见，不可见，翻页
                if not self.element_is_visible(args, context):
                    size = self.get_current_page_size()
                    # 设置滑动的大小
                    start_x = size['width'] * 0.5
                    start_y = size['height'] * 0.8
                    end_x = size['width'] * 0.5
                    end_y = size['height'] * 0.3
                    self.driver.swipe(start_x=start_x, start_y=start_y, end_x=end_x, end_y=end_y, duration=200)
                    old_page = new_page
                    new_page = self.driver.page_source
                else:
                    break
            else:
                raise ValueError(f'滑动查找{context}元素失败')

    def toast(self, args: tuple, context: str) -> str:
        '''
        获取toast弹窗的文本信息
        :param args:
        :param context:
        :return:
        '''
        if self.element_is_exist(args, context):
            return self.driver.find_element(*args).text
        else:
            raise AssertionError(f"获取{context}元素text值失败")

    def return_button(self, args=None, context=None):
        '''
        系统返回键操作
        :return:
        '''
        try:
            self.driver.keyevent(4)
        except Exception as E:
            raise AssertionError("点击返回键失败")

    def search_button(self, args=None, context=None):
        '''
        调用谷歌输入法的搜索按钮
        :return:
        '''
        # command = 'adb shell ime set com.sohu.inputmethod.sogou/.SogouIME'
        # os.system(command)
        self.driver.keyevent(66)


if __name__ == '__main__':
    # print(time.strftime('%Y-%m-%d %H:%M:%S'))
    # print(time.strptime('2021-07-26 17:12:52', '%Y-%m-%d %H:%M:%S'))
    # print(time.mktime(time.strptime('2021-07-26 17:12:52', '%Y-%m-%d %H:%M:%S')))
    print('a' * 100)
